﻿using System;
using System.Collections.Generic;
using GigaSite.Domain.Entities;
using GigaSite.Domain.Interfaces.Repositories;

namespace GigaSite.Domain.DAL.Repositories
{
    /// <summary>
    /// Реализация репозитория для работы с категориями каталога
    /// </summary>
    public class CategoriesRepository: BaseRepository<Category>, ICategoriesRepository
    {
        /// <summary>
        /// Базовый конструктор
        /// </summary>
        /// <param name="dataContext"></param>
        public CategoriesRepository(GigaDataContext dataContext) : base(dataContext)
        {
        }

        /// <summary>
        /// Загружает указанную сущность по ее идентификатору
        /// </summary>
        /// <param name="id">Идентификатор сущности</param>
        /// <returns>Сущность с указанным идентификатором или Null</returns>
        public override Category Load(long id)
        {
            return Find(c => c.Id == id);
        }

        /// <summary>
        /// Возвращает коллекцию корневых категорий каталога
        /// </summary>
        /// <returns>Коллекция категорий</returns>
        public IEnumerable<Category> GetRootCategories()
        {
            return Search(c => c.ParentId == -1);
        }

        /// <summary>
        /// Возвращает коллекцию дочерних категорий указанной категории
        /// </summary>
        /// <param name="categoryId">Идентификатор категории</param>
        /// <returns>Коллекция категорий</returns>
        public IEnumerable<Category> GetChildCategories(long categoryId)
        {
            return Search(c => c.ParentId == categoryId);
        }

        /// <summary>
        /// Возвращает коллекцию дочерних категорий указанной категории
        /// </summary>
        /// <param name="category">Объект категории</param>
        /// <returns>Коллекция категорий</returns>
        public IEnumerable<Category> GetChildCategories(Category category)
        {
            return category.ChildCategories;
        }

        /// <summary>
        /// Возвращает коллекцию категорий для сущности указанного типа, возвращаются только не пустые категории
        /// </summary>
        /// <typeparam name="T">Тип сущности категории для которой нужно вычленить</typeparam>
        /// <returns>Иерархия категорий в которых есть сущности указанного типа</returns>
        public IEnumerable<Category> GetNonEmptyCategories<T>() where T : class
        {
            throw new NotImplementedException("Еще не реализовано"); // TODO: реализовать многоуровневое отсеивание на основе типа сущности
        }

        /// <summary>
        /// Возвращает категорию с указанным системным именем
        /// </summary>
        /// <param name="systemName">Системное имя категории</param>
        /// <returns>Категория либо null</returns>
        public Category GetCategoryBySystemName(string systemName)
        {
            return Find(c => c.SystemName == systemName);
        }

        /// <summary>
        /// Удаляет сущность из репозитория
        /// </summary>
        /// <param name="entity">Сущность для удаления</param>
        public override void Delete(Category entity)
        {
            // Удаляем все дочерние категории
            foreach (var childCategory in entity.ChildCategories)
            {
                Delete(childCategory);
            }

            // Вызываем базовый метод
            base.Delete(entity);
        }
    }
}